package org.agent.aigccore.basic.exception;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.agent.aigccore.model.vo.Response;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    
    /**
     * 处理自定义认证异常
     */
    @ExceptionHandler(AuthException.class)
    public ResponseEntity<Response<?>> handleAuthException(AuthException e, HttpServletRequest request) {
        log.error("[AuthException] path={}, errorCode={}, message={}", 
                request.getRequestURI(), e.getErrorCode(), e.getMessage(), e);
        
        Response<?> response = Response.fail(
                e.getErrorCode() != null ? e.getErrorCode() : "AUTH_ERROR",
                e.getMessage()
        ).withPath(request.getRequestURI());
        
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
    }
    
    /**
     * 处理自定义用户异常
     */
    @ExceptionHandler(UserException.class)
    public ResponseEntity<Response<?>> handleUserException(UserException e, HttpServletRequest request) {
        log.error("[UserException] path={}, errorCode={}, message={}", 
                request.getRequestURI(), e.getErrorCode(), e.getMessage(), e);
        
        Response<?> response = Response.fail(
                e.getErrorCode() != null ? e.getErrorCode() : "USER_ERROR",
                e.getMessage()
        ).withPath(request.getRequestURI());
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }
    
    /**
     * 处理Spring Security认证异常
     */
    @ExceptionHandler(AuthenticationException.class)
    public ResponseEntity<Response<?>> handleAuthenticationException(AuthenticationException e, HttpServletRequest request) {
        log.error("[SpringAuthException] path={}, message={}", request.getRequestURI(), e.getMessage(), e);
        
        Response<?> response = Response.fail(
                "AUTHENTICATION_FAILED",
                "认证失败: " + e.getMessage()
        ).withPath(request.getRequestURI());
        
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
    }
    
    /**
     * 处理访问拒绝异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseEntity<Response<?>> handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        log.error("[AccessDenied] path={}, message={}", request.getRequestURI(), e.getMessage(), e);
        
        Response<?> response = Response.fail(
                "ACCESS_DENIED",
                "访问被拒绝: " + e.getMessage()
        ).withPath(request.getRequestURI());
        
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(response);
    }

    /**
     * 处理参数校验相关异常
     */
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class, MethodArgumentTypeMismatchException.class, IllegalArgumentException.class})
    public ResponseEntity<Response<?>> handleValidationException(Exception e, HttpServletRequest request) {
        log.error("[Validation] path={}, message={}", request.getRequestURI(), e.getMessage(), e);
        
        Response<?> response = Response.fail(
                "VALIDATION_ERROR",
                "请求参数错误: " + e.getMessage()
        ).withPath(request.getRequestURI());
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }
    
    /**
     * 处理通用异常
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Response<?>> handleException(Exception e, HttpServletRequest request) {
        log.error("[Unhandled] path={}, message={}", request.getRequestURI(), e.getMessage(), e);
        
        Response<?> response = Response.fail(
                "INTERNAL_ERROR",
                "服务器内部错误: " + e.getMessage()
        ).withPath(request.getRequestURI());
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
}